import unittest
from TestRPC import InClass, CurrentClass
import TestTimeout
import threading
import sys
import time


class MqRPCTest(unittest.TestCase):

    def setUp(self):
        print("running " + sys._getframe().f_code.co_name)
        self.inClassClient = InClass()
        self.inClassClientAsync = InClass(True)
        self.currentClassClient = CurrentClass()

    def tearDown(self):
        print("running " + sys._getframe().f_code.co_name)
        self.inClassClient.close_connection()
        self.inClassClientAsync.close_connection()
        self.currentClassClient.close_connection()

    @classmethod
    def tearDownClass(cls):
        # 其父类静态函数 只要执行一次就行了
        InClass.close_local_dead_msg_consumer()

    def test_simpleUse(self):
        print("running " + sys._getframe().f_code.co_name)
        # 测试设置current class
        self.assertEqual(self.currentClassClient.add(2, 3), 5)
        self.assertEqual(self.currentClassClient.minus(2, 3), -1)
        self.assertEqual(self.currentClassClient.multi(2, 3), 6)
        self.assertEqual(self.currentClassClient.div(4, 2), 2)

        # 测试直接在class中装饰方法能否使用
        self.assertEqual(self.inClassClient.add(1, 2), 3)
        self.assertEqual(self.inClassClient.minus(6, 2), 4)
        self.assertEqual(self.inClassClient.multi(1, 2), 2)
        self.assertEqual(self.inClassClient.div(2, 1), 2)
        # 同时上面 同样测试了同步RPC的有效性

    def test_asyncRpc(self):
        print("running " + sys._getframe().f_code.co_name)
        # 测试异步
        add_corr_id = self.inClassClientAsync.add(1, 3)
        minus_corr_id = self.inClassClientAsync.minus(6, 5)
        multi_corr_id = self.inClassClientAsync.multi(1, 3)
        div_corr_id = self.inClassClientAsync.div(6, 2)
        self.assertEqual(self.inClassClientAsync.get_response(add_corr_id), 4)
        self.assertEqual(self.inClassClientAsync.get_response(minus_corr_id), 1)
        self.assertEqual(self.inClassClientAsync.get_response(multi_corr_id), 3)
        self.assertEqual(self.inClassClientAsync.get_response(div_corr_id), 3)

    def test_multiThread(self):
        # 用于多线程测试的量
        self.mutex = threading.Lock()
        self.count = 0
        print("running " + sys._getframe().f_code.co_name)
        # 测试10个线程同时使用
        for _ in range(10):
            t = threading.Thread(target=self._thread)
            t.start()
        while True:
            if self.count == 10:
                break

    def _thread(self):
        print("running " + sys._getframe().f_code.co_name + " " + str(threading.get_ident()))
        # 同步
        self.assertEqual(self.inClassClient.add(6, 4), 10)
        self.assertEqual(self.inClassClient.minus(6, 4), 2)

        # 异步
        add_id = self.inClassClientAsync.add(9, 10)
        self.assertEqual(self.inClassClientAsync.get_response(add_id), 19)
        print("ran " + sys._getframe().f_code.co_name + " " + str(threading.get_ident()))
        self.mutex.acquire()
        self.count += 1
        self.mutex.release()

    def test_timeout(self):
        print("running " + sys._getframe().f_code.co_name)
        inClassClient = TestTimeout.InClass()
        try:
            inClassClient.signal_request_timeout = "1000"  # 超时时间1s
            # 同步
            inClassClient.add(2, 3)
        except Exception as e:
            print("同步捕获异常:"+str(e))
            self.assertEqual("100", e.status)
        finally:
            inClassClient.close_connection()

        inClassClient = TestTimeout.InClass(True)
        try:
            inClassClient.signal_request_timeout = "1000"  # 超时时间1s
            # 同步
            corr_id = inClassClient.add(2, 3)
            inClassClient.get_response(corr_id)
        except Exception as e:
            print("异步捕获异常:" + str(e))
            self.assertEqual("100", e.status)
        finally:
            inClassClient.close_connection()

        # 其父类静态函数 只要执行一次就行了
        InClass.close_local_dead_msg_consumer()
        inClassClient.close_local_dead_msg_consumer()

        # try:
        #     timeout_server = TestTimeout.InClass(True)
        #     timeout_server.signal_request_timeout = 1000  # 超时时间1s
        #     # 异步
        #     timeout_server.get_response(timeout_server.add(2, 3))
        # except Exception as e:
        #     print("捕获异常:"+str(e))
        #     self.assertEqual("100", e.status)


if __name__ == "__main__":
    unittest.main()
